package org.kernely.stream.dao;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import org.kernely.persistence.service.SessionService;
import org.kernely.security.persistence.User;
import org.kernely.stream.persistence.Stream;
import org.osgi.service.component.ComponentContext;

public class StreamDAO {
	/**
	 * SessionService service
	 */
	private static SessionService service;
	
	/**
	 * The stream dao instance
	 */
	private static StreamDAO instance;

	/**
	 * Store the stream dao instance 
	 * @return the stream dao
	 */
	public static StreamDAO getInstance() {
		return instance;
	}
	
	/**
	 * Set the persistence session service
	 * @param sessionService the session service to set
	 */
	public final void setPersistenceService(SessionService sessionService) {
		service = sessionService;
	}

	/**
	 * Activate the component, called by SC runtime
	 * @param ctxt the activation context
	 */
	protected final void activate(ComponentContext ctxt) {
		instance = this;
	}
	
	/**
	 * Gets the session service.
	 * 
	 * @return the session service
	 */
	public static SessionService getService() {
		return service;
	}

	/**
	 * Sets the session service.
	 * 
	 * @param service
	 *            the session service to set
	 */
	public static void setService(SessionService service) {
		StreamDAO.service = service;
	}
	
	/**
	 * Get all the streams.
	 * @return A set containing all the streams.
	 */
	public final Set<Stream> getAllStream(){
		Session session = service.getSession();
		return new HashSet<Stream>(session.createCriteria(Stream.class).list());
	}
	
	/**
	 * Get the streams subscribed by the user have subscribed to.
	 * @param u The user.
	 * @return A set containing the streams.
	 */
	public final Set<Stream> getUserSubscribedStream(User u){
		Session session = service.getSession();
		String req = "SELECT * FROM kernely_stream, kernely_stream_subscription WHERE kernely_stream.stream_id = kernely_stream_subscription.fk_stream AND kernely_stream_subscription.fk_user = "+ u.getId();
		Query query = session.createSQLQuery(req).addEntity(Stream.class);
		return new HashSet<Stream>(query.list());
	}
	
	/**
	 * Find a stream using its DB id.
	 * @param id The id of the stream in database.
	 * @return THe stream.
	 */
	public final Stream findStreamById(int id){
		Session session = service.getSession();
		Criteria crit = session.createCriteria(Stream.class);
		crit.add(Restrictions.like("id", id));
		return (Stream) crit.list().get(0);
	}
	
	/**
	 * Save a new stream in DB.
	 * @param s The stream to save.
	 */
	public final void saveStream(Stream s){
		Session session = service.getSession();
		session.save(s);
	}
	
	/**
	 * Update an existing stream in DB.
	 * @param s The stream to update.
	 */
	public final void updateStream(Stream s){
		Session session = service.getSession();
		session.update(s);
	}
	
	/**
	 * Find a stream, using his uid and his category
	 * @param category The category of the stream (for example "Streams/Users").
	 * @param uid The uid of the stream.
	 * @return
	 */
	public final Stream findStream(String category, String uid){
		Session session = service.getSession();
		Criteria crit = session.createCriteria(Stream.class);
		crit.add(Restrictions.like("uid", uid));
		crit.add(Restrictions.like("category", category));
		List result = crit.list();
		Stream s = null;
		if (result != null && result.size() > 0){
			s = (Stream) result.get(0);			
		}
		return s;
	}
}
